{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "<center>\n",
    "<img src=\"https://habrastorage.org/files/fd4/502/43d/fd450243dd604b81b9713213a247aa20.jpg\">\n",
    "<br>    \n",
    "    \n",
    "<div style=\"font-weight: 700; font-size: 20px;\"> Open Machine Learning Course [mlcourse.ai](https://mlcourse.ai) </div>\n",
    "\n",
    "<br>\n",
    "<center>\n",
    "\n",
    "Auteur : Vitaly Radchenko (@vradchenko). Traduit par : [Ousmane Cissé](https://github.com/oussou-dev.com) .Ce matériel est soumis aux termes et conditions de la licence [Creative Commons CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/). L'utilisation gratuite est autorisée à des fins non commerciales.</center></center>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "<div style=\"font-weight: 700; font-size: 30px;\"> <center>Mission # 5 (démo) </center> </div>\n",
    "\n",
    "<br>\n",
    "\n",
    "<div style=\"font-weight: 700; font-size: 23px;\"> <center><center>Régression logistique et forêt aléatoire dans un problème de \"credit scoring\"</center> </center> </div>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "Dans cette affectation, vous allez construire des modèles et répondre aux questions en utilisant des données sur la notation de crédit.\n",
    "\n",
    "Veuillez écrire votre code dans les cellules ci-dessous (\"Your code here\"). Ensuite, répondez aux questions du [formulaire](https://docs.google.com/forms/d/1gKt0DA4So8ohKAHZNCk58ezvg7K_tik26d9QND7WC6M/edit).\n",
    "\n",
    "Commençons par un exercice d'échauffement."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "**Question 1.** Il y a 5 jurés dans une salle d'audience. Chacun d'entre eux peut identifier correctement la culpabilité du défendeur avec une probabilité de 70%, indépendamment l'un de l'autre. Quelle est la probabilité que les jurés parviennent conjointement au verdict correct si la décision finale est prise à la majorité des voix?\n",
    "\n",
    "1. 70,00%\n",
    "2. 83,20%\n",
    "3. 83,70%\n",
    "4. 87,50%"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "Génial! Passons à l'apprentissage automatique.\n",
    "\n",
    "## Présentation du problème de \"credit scoring\"\n",
    "\n",
    "### Problème\n",
    "\n",
    "Prédisez si le client remboursera son crédit dans les 90 jours. Ceci est un problème de classification binaire; nous allons affecter les clients dans les bonnes ou les mauvaises catégories en fonction de nos prévisions.\n",
    "\n",
    "### Description des données\n",
    "\n",
    "\n",
    "| Feature | Variable Type | Value Type | Description |\n",
    "|:--------|:--------------|:-----------|:------------|\n",
    "| age | Input Feature | integer | Customer age |\n",
    "| DebtRatio | Input Feature | real | Total monthly loan payments (loan, alimony, etc.) / Total monthly income percentage |\n",
    "| NumberOfTime30-59DaysPastDueNotWorse | Input Feature | integer | The number of cases when client has overdue 30-59 days (not worse) on other loans during the last 2 years |\n",
    "| NumberOfTimes90DaysLate | Input Feature | integer | Number of cases when customer had 90+dpd overdue on other credits |\n",
    "| NumberOfTime60-89DaysPastDueNotWorse | Input Feature | integer | Number of cased when customer has 60-89dpd (not worse) during the last 2 years |\n",
    "| NumberOfDependents | Input Feature | integer | The number of customer dependents |\n",
    "| SeriousDlqin2yrs | Target Variable | binary: <br>0 or 1 | Customer hasn't paid the loan debt within 90 days |\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "Mettons en place notre environnement:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "958b2cd2a45ac297fb144c47f2e993e0a5fab169"
   },
   "outputs": [],
   "source": [
    "# Disable warnings in Anaconda\n",
    "import warnings\n",
    "\n",
    "warnings.filterwarnings(\"ignore\")\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "\n",
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "\n",
    "sns.set()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "57846c0c4a90698c2d1e4577a1d338566a0511d2"
   },
   "outputs": [],
   "source": [
    "from matplotlib import rcParams\n",
    "\n",
    "rcParams[\"figure.figsize\"] = 11, 8"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "Écrivons la fonction qui remplacera *NaN* par la médiane de chaque colonne."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "d4b4c073dc7d54908594df01f032b249b2ee461e"
   },
   "outputs": [],
   "source": [
    "def fill_nan(table):\n",
    "    for col in table.columns:\n",
    "        table[col] = table[col].fillna(table[col].median())\n",
    "    return table"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "Maintenant, lisez les données:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "63c902c7d1d18943bd460ee15c73d8a10e5d8ff3"
   },
   "outputs": [],
   "source": [
    "data = pd.read_csv(\"../input/credit_scoring_sample.csv\")\n",
    "data.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "Regardez les types de variables:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "8fdf8aa51c7febd4ee2d7914129888b01703b716"
   },
   "outputs": [],
   "source": [
    "data.dtypes"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "Vérifiez le solde de la classe:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "35216e0b707d378f851ea1bc9602890998e1ec97"
   },
   "outputs": [],
   "source": [
    "ax = data[\"SeriousDlqin2yrs\"].hist(orientation=\"horizontal\", color=\"red\")\n",
    "ax.set_xlabel(\"number_of_observations\")\n",
    "ax.set_ylabel(\"unique_value\")\n",
    "ax.set_title(\"Target distribution\")\n",
    "\n",
    "print(\"Distribution of the target:\")\n",
    "data[\"SeriousDlqin2yrs\"].value_counts() / data.shape[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "Séparez les noms de variables d'entrée en excluant la cible:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "4d6c4a84ed3fcb2447f11b1d0a08a0b4fefcbaf7"
   },
   "outputs": [],
   "source": [
    "independent_columns_names = [x for x in data if x != \"SeriousDlqin2yrs\"]\n",
    "independent_columns_names"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "Appliquez la fonction pour remplacer les valeurs *NaN*:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "4e1e6638b8c50ee094b8d9f3af693fda035aa8c4"
   },
   "outputs": [],
   "source": [
    "table = fill_nan(data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "Séparez la variable cible et les caractéristiques en entrée:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "55248eae34b1abf6337dbce543195d9adef29e19"
   },
   "outputs": [],
   "source": [
    "X = table[independent_columns_names]\n",
    "y = table[\"SeriousDlqin2yrs\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "## Bootstrapping"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "**Question 2.** Faire une estimation par intervalle de l'âge moyen des clients qui ont retardé le remboursement à un niveau de confiance de 90 %. Utilisez l'exemple de l'article comme référence, si nécessaire. Aussi, utilisez `np.random.seed(0)` comme précédemment. Quelle est l'estimation de l'intervalle qui en résulte ?\n",
    "\n",
    "1. 52.59 - 52.86\n",
    "2. 45,71 - 46,13\n",
    "3. 45,68 - 46,17\n",
    "4. 52,56 - 52,88"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "0f42f4204cfa87434c31e5e09e270a42bd61850c"
   },
   "outputs": [],
   "source": [
    "# Your code here"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "## Régression logistique"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "Préparons-nous à utiliser la régression logistique :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "fea9173ba030a164de7d4da05d83bce7a881e92f"
   },
   "outputs": [],
   "source": [
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.model_selection import GridSearchCV, StratifiedKFold"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "Maintenant, nous allons créer un modèle `LogisticRegression` et utiliser `class_weight='balanced'` pour compenser nos classes déséquilibrées."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "92292d0240a272fc6c3948069ef2fc0b9f165926"
   },
   "outputs": [],
   "source": [
    "lr = LogisticRegression(random_state=5, class_weight=\"balanced\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "Essayons de trouver le meilleur coefficient de régularisation, qui est le coefficient `C` pour la régression logistique. Ensuite, nous aurons un modèle optimal qui n’est pas sur-ajusté et qui est un bon prédicteur de la variable cible."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "77fff55d1042a6b6b906e4f8af2e977966e9ad55"
   },
   "outputs": [],
   "source": [
    "parameters = {\"C\": (0.0001, 0.001, 0.01, 0.1, 1, 10)}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "Afin de trouver la valeur optimale de `C`, appliquons une validation stratifiée à 5 niveaux (5-fold) et examinons le _ROC AUC_ par rapport à différentes valeurs du paramètre` C`. Utilisez la fonction `StratifiedKFold` pour cela :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "296cc7dbf4b702d3170f3515f4c431da8dd02486"
   },
   "outputs": [],
   "source": [
    "skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "L'une des métriques importantes de la qualité du modèle est la *zone sous la courbe (AUC)*. Le *ROC AUC* varie de 0 à 1. Plus le ROC AUC est proche de 1, meilleure est la qualité du modèle de classification."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "**Question 3.** Effectuez une *Grid Search* avec la métrique de scoring \"roc_auc\" pour le paramètre `C`. Quelle valeur du paramètre `C` est optimale ?\n",
    "\n",
    "1. 0,0001\n",
    "2. 0,001\n",
    "3. 0,01\n",
    "4. 0,1\n",
    "5. 1\n",
    "6. 10"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "ea814fc22242f846757a81fda5d63b1e8d71b81c"
   },
   "outputs": [],
   "source": [
    "# Your code here"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "**Question 4.** Peut-on considérer le meilleur modèle stable? Le modèle est *stable* si l'écart type lors de la validation est inférieur à 0,5%. Enregistrez la valeur *ROC AUC* du meilleur modèle. Cela sera utile pour les tâches suivantes.\n",
    "\n",
    "1. oui\n",
    "2. non"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "27e2211b96120fad6ed989c4b55a033184b442ac"
   },
   "outputs": [],
   "source": [
    "# Your code here"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "## Importance des caractéristiques (Feature Importance)\n",
    "\n",
    "**Question 5.** _L'importance d'une caractéristique_ est définie par la valeur absolue de son coefficient correspondant. Tout d'abord, vous devez normaliser toutes les valeurs des caractéristiques pour qu'il soit valide de les comparer. Quelle est la caractéristique la plus importante pour le meilleur modèle de régression logistique ?\n",
    "1. age\n",
    "2. NumberOfTime30-59DaysPastDueNotWorse\n",
    "3. DebtRatio\n",
    "4. NumberOfTimes90DaysLate\n",
    "5. NumberOfTime60-89DaysPastDueNotWorse\n",
    "6. MonthlyIncome\n",
    "7. NumberOfDependents"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "42af010963a6d4c1526c3499031dcec274a2b460"
   },
   "outputs": [],
   "source": [
    "# Your code here"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "**Question 6.** Calculez l'impact de `DebtRatio` sur notre prédiction à l'aide de la [fonction softmax](https://en.wikipedia.org/wiki/Softmax_function). Quelle est sa valeur?\n",
    "\n",
    "1. 0.38\n",
    "2. -0.02\n",
    "3. 0.11\n",
    "4. 0.24"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "de4195b2f9012f17ad3b2999622404c303d4fd0a"
   },
   "outputs": [],
   "source": [
    "# Your code here"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "**Question 7.** Voyons comment nous pouvons interpréter l’impact de nos caractéristiques. Pour cela, recalculez la régression logistique avec des valeurs absolues, c'est-à-dire sans mise à l'échelle. Ensuite, modifiez l'âge du client en ajoutant 20 ans, en laissant les autres caractéristiques inchangées. Combien de fois le risque que le client ne rembourse pas sa dette augmente-t-il? Vous pouvez trouver un exemple de calcul théorique [ici](https://www.unm.edu/~schrader/biostat/bio2/Spr06/lec11.pdf).\n",
    "\n",
    "1. -0.01\n",
    "2. 0.70\n",
    "3. 8.32\n",
    "4. 0.66"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "988fd621a0f8b9cee200d1798a1535c941615dab"
   },
   "outputs": [],
   "source": [
    "# Your code here"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "## Forêt aléatoire (random forest)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "Importez le classifieur Forêt aléatoire:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "8252905ea996ff08abc33560f7d144af8c53b56d"
   },
   "outputs": [],
   "source": [
    "from sklearn.ensemble import RandomForestClassifier"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "Initialiser une forêt aléatoire avec 100 arbres et équilibrer les classes cibles:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "d9fcfad198b9bc5f66c916b8179b2edf7d1d6067"
   },
   "outputs": [],
   "source": [
    "rf = RandomForestClassifier(\n",
    "    n_estimators=100, n_jobs=-1, random_state=42, class_weight=\"balanced\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "Nous rechercherons les meilleurs paramètres parmi les valeurs suivantes:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "4b04ae1ed65286fbd4e90511f524de20177f580a"
   },
   "outputs": [],
   "source": [
    "parameters = {\n",
    "    \"max_features\": [1, 2, 4],\n",
    "    \"min_samples_leaf\": [3, 5, 7, 9],\n",
    "    \"max_depth\": [5, 10, 15],\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "Nous allons également utiliser à nouveau la validation stratifiée à k-fold. Vous devriez toujours avoir la variable `skf`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "**Question 8.** De combien, la *ROC AUC* du meilleur modèle de forêt aléatoire est-elle supérieure à celle de la meilleure régression logistique après validation?\n",
    "\n",
    "1. 4%\n",
    "2. 3%\n",
    "3. 2%\n",
    "4. 1%"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "f7adb918cb3a5b3b45527e77ca0eb70f78ecce55"
   },
   "outputs": [],
   "source": [
    "# Your code here"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "**Question 9.** Quelle caractéristique a l’impact le plus faible dans le modèle de forêt aléatoire?\n",
    "\n",
    "1. age\n",
    "2. NumberOfTime30-59DaysPastDueNotWorse\n",
    "3. DebtRatio\n",
    "4. NumberOfTimes90DaysLate\n",
    "5. NumberOfTime60-89DaysPastDueNotWorse\n",
    "6. MonthlyIncome\n",
    "7. NumberOfDependents"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "bbb93f0ced33c8a65894bfd0bb26c5fbe534394c"
   },
   "outputs": [],
   "source": [
    "# Your code here"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "**Question 10.** Quel est l'avantage le plus significatif de l'utilisation de la *Régression logistique* par rapport à la *Forêt aléatoire* pour résoudre ce problème?\n",
    "\n",
    "1. passé moins de temps pour l'ajustement du modèle;\n",
    "2. Moins de variables à itérer;\n",
    "3. interprétabilité des caractéristiques;\n",
    "4. Propriétés linéaires de l'algorithme."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "## Bagging (Ensachage)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "Importer des modules et configurer les paramètres pour le Bagging :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "ea666be2e57e478428cc553fd7e2ecd5d7ca8bee"
   },
   "outputs": [],
   "source": [
    "from sklearn.ensemble import BaggingClassifier\n",
    "from sklearn.model_selection import RandomizedSearchCV, cross_val_score\n",
    "\n",
    "parameters = {\n",
    "    \"max_features\": [2, 3, 4],\n",
    "    \"max_samples\": [0.5, 0.7, 0.9],\n",
    "    \"base_estimator__C\": [0.0001, 0.001, 0.01, 1, 10, 100],\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "**Question 11.** Installez un classifieur bagging avec `random_state = 42`. Pour les classifieurs de base, utilisez 100 régresseurs logistiques et utilisez `RandomizedSearchCV` au lieu de `GridSearchCV`. Il faudra beaucoup de temps pour parcourir les 54 variantes, donc définissez le nombre maximal d'itérations pour `RandomizedSearchCV` sur 20. N'oubliez pas de définir les paramètres `cv` et `random_state=1`. Quel est le meilleur *ROC AUC* que vous obtenez ?\n",
    "\n",
    "1. 80,75%\n",
    "2. 80,12%\n",
    "3. 79,62%\n",
    "4. 76,50%"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "_uuid": "2c2e9cc7930cc6c3816f8538385d1f78c12b104b"
   },
   "outputs": [],
   "source": [
    "# Your code here"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "fr"
   },
   "source": [
    "**Question 12.** Donnez une interprétation des meilleurs paramètres pour le Bagging. Pourquoi ces valeurs de `max_features` et de` max_samples` sont-elles les meilleures?\n",
    "\n",
    "1. Pour le bagging, il est important d'utiliser le moins de caractéristiques possible.\n",
    "2. Le bagging fonctionne mieux sur de petits échantillons.\n",
    "3. Moins de corrélation entre les modèles individuels;\n",
    "4. Plus le nombre de caractéristiques est élevé, plus la perte d'informations est faible."
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "hide_input": false,
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.4"
  },
  "nbTranslate": {
   "displayLangs": [
    "*"
   ],
   "hotkey": "alt-t",
   "langInMainMenu": true,
   "sourceLang": "en",
   "targetLang": "fr",
   "useGoogleTranslate": true
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
